Skip to content

Fix Android Maestro e2e: eliminate UIAutomator2 rendering race condition#38

Merged
gfauredev merged 17 commits intomainfrom
copilot/harmonize-ci-cd-workflow
Feb 26, 2026
Merged

Fix Android Maestro e2e: eliminate UIAutomator2 rendering race condition#38
gfauredev merged 17 commits intomainfrom
copilot/harmonize-ci-cd-workflow

Conversation

Copy link
Contributor

Copilot AI commented Feb 22, 2026

Maestro e2e tests consistently failed at the timeout boundary. Root cause: launchApp cold-starts the app each flow, and Maestro's UIAutomator2 polling (~100ms interval) forces Chrome WebView to serialize its accessibility tree on Android's main thread, starving the Dioxus WebSocket. Rendering time expanded to fill exactly the timeout value (confirmed across two runs: 60.56s with 60s timeout, ~90s with 90s timeout).

Changes

  • maestro/*.yaml — Remove launchApp from all 3 flows. The app is pre-launched by CI before Maestro starts; without launchApp, Maestro never sends am force-stop/am start, so the already-rendered app stays alive. extendedWaitUntil passes on the first UIAutomator2 poll.
  • maestro/*.yaml — Reduce extendedWaitUntil timeout 90000 → 30000 ms. With a pre-rendered app this is conservative; 30s covers UIAutomator2 server startup.
  • .github/workflows/ci.yml — Increase pre-launch sleep 30 → 60 s. App renders in ~22s without polling interference; 60s ensures it is fully rendered before Maestro initializes.

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…aestro tests

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title [WIP] Harmonize CI on PRs and CD on main branch Harmonize CI/CD: CI on PRs, CD on main; move Maestro e2e to CI; fix Maestro tests Feb 22, 2026
Copilot AI requested a review from gfauredev February 22, 2026 10:15
@github-actions
Copy link

github-actions bot commented Feb 22, 2026

🧪 Unit Tests & Coverage

Test Results

info: cargo-llvm-cov currently setting cfg(coverage); you can opt-out it by passing --no-cfg-coverage
�[1m�[92m    Updating�[0m crates.io index
�[1m�[92m   Compiling�[0m log-workout v0.1.0 (/home/runner/work/LogOut/LogOut)
�[1m�[92m    Finished�[0m `test` profile [unoptimized + debuginfo] target(s) in 7.29s
�[1m�[92m     Running�[0m unittests src/main.rs (target/llvm-cov-target/debug/deps/log_workout-ab1956251af3abe0)

running 121 tests
test models::tests::all_forces_serde_round_trip ... ok
test models::tests::all_categories_serde_round_trip ... ok
test models::tests::all_equipment_serde_round_trip ... ok
test models::tests::category_all_contains_every_variant ... ok
test models::tests::all_muscles_serde_round_trip ... ok
test models::tests::category_display_all_variants ... ok
test models::tests::category_round_trip ... ok
test models::tests::distance_display_fractional_km ... ok
test models::tests::distance_display_metres ... ok
test models::tests::distance_display_whole_km ... ok
test models::tests::equipment_all_contains_every_variant ... ok
test models::tests::equipment_display_all_variants ... ok
test models::tests::equipment_round_trip ... ok
test models::tests::exercise_backward_compat_missing_optional_fields ... ok
test models::tests::exercise_full_json_deserialization ... ok
test models::tests::exercise_get_image_url_full_url_passthrough ... ok
test models::tests::exercise_get_first_image_url_none ... ok
test models::tests::exercise_get_image_url_by_index ... ok
test models::tests::exercise_get_first_image_url_some ... ok
test models::tests::exercise_level_none_when_missing_from_json ... ok
test models::tests::exercise_level_some_when_present_in_json ... ok
test models::tests::exercise_log_duration_saturates_on_underflow ... ok
test models::tests::exercise_log_duration_seconds ... ok
test models::tests::exercise_log_duration_seconds_none_when_incomplete ... ok
test models::tests::exercise_log_is_complete ... ok
test models::tests::exercise_log_force_none_is_omitted_in_json ... ok
test models::tests::exercise_log_serde_round_trip_with_all_fields ... ok
test models::tests::exercise_minimal ... ok
test models::tests::exercise_optional_fields_none ... ok
test models::tests::find_active_session_returns_first_without_end_time ... ok
test models::tests::find_active_session_returns_none_when_all_finished ... ok
test models::tests::find_active_session_returns_none_for_empty_list ... ok
test models::tests::finish_session_cancelled_session_is_not_stored ... ok
test models::tests::finish_session_with_exercises_is_stored ... ok
test models::tests::force_all_contains_every_variant ... ok
test models::tests::force_display_all_variants ... ok
test models::tests::force_has_reps ... ok
test models::tests::format_time_hours ... ok
test models::tests::format_time_minutes_seconds ... ok
test models::tests::get_current_timestamp_returns_reasonable_value ... ok
test models::tests::level_display_all_variants ... ok
test models::tests::level_serde_round_trip ... ok
test models::tests::mechanic_display_all_variants ... ok
test models::tests::mechanic_serde_round_trip ... ok
test models::tests::muscle_all_contains_every_variant ... ok
test models::tests::format_time_boundary_values ... ok
test models::tests::muscle_display_all_variants ... ok
test models::tests::muscle_round_trip ... ok
test models::tests::parse_distance_km_invalid ... ok
test models::tests::parse_distance_km_large_value_clamped ... ok
test models::tests::parse_distance_km_nan_and_infinity ... ok
test models::tests::parse_distance_km_valid ... ok
test models::tests::parse_weight_kg_invalid ... ok
test models::tests::parse_weight_kg_large_value_clamped ... ok
test models::tests::parse_weight_kg_nan_and_infinity ... ok
test models::tests::parse_weight_kg_valid ... ok
test models::tests::pending_ids_include_repeated_exercises ... ok
test models::tests::remove_first_occurrence_from_pending_ids ... ok
test models::tests::session_with_only_pending_exercises_is_cancelled ... ok
test models::tests::weight_display_fractional_kg ... ok
test models::tests::user_exercise_serialization_with_all_fields ... ok
test models::tests::weight_display_whole_kg ... ok
test models::tests::weight_display_zero ... ok
test models::tests::workout_serde_round_trip ... ok
test models::tests::workout_exercise_serde_round_trip ... ok
test models::tests::workout_session_backward_compat_missing_pending_ids ... ok
test models::tests::workout_session_current_exercise_fields_default_none ... ok
test models::tests::workout_session_is_active ... ok
test models::tests::workout_session_is_cancelled_when_no_exercises ... ok
test models::tests::workout_session_is_not_cancelled_when_has_exercises ... ok
test models::tests::workout_session_new_has_empty_pending_ids ... ok
test models::tests::workout_session_new_has_no_end_time ... ok
test models::tests::workout_session_pending_ids_serialization_round_trip ... ok
test models::tests::workout_set_serde_round_trip ... ok
test models::tests::workout_session_with_exercise_logs_serde ... ok
test models::tests::workout_set_without_optionals ... ok
test services::exercise_db::tests::exercises_json_url_uses_fork ... ok
test services::exercise_db::tests::get_equipment_types_deduplicates ... ok
test services::exercise_db::tests::get_equipment_types_only_returns_some_equipment ... ok
test services::exercise_db::tests::get_exercise_by_id_found ... ok
test services::exercise_db::tests::get_exercise_by_id_not_found ... ok
test services::exercise_db::tests::get_muscle_groups_deduplicates ... ok
test services::exercise_db::tests::get_muscle_groups_only_returns_primary_muscles ... ok
test services::exercise_db::tests::is_refresh_due_false_at_exact_interval_boundary ... ok
test services::exercise_db::tests::is_refresh_due_false_when_recent ... ok
test services::exercise_db::tests::is_refresh_due_true_when_no_timestamp ... ok
test services::exercise_db::tests::is_refresh_due_true_when_stale ... ok
test services::exercise_db::tests::native::clear_fetch_cache_removes_config_value ... ok
test services::exercise_db::tests::native::download_exercises_returns_empty_vec_on_200_empty_json ... ok
test services::exercise_db::tests::native::download_exercises_returns_error_on_connection_refused ... ok
test services::exercise_db::tests::native::download_exercises_returns_error_on_http_404 ... ok
test services::exercise_db::tests::native::is_refresh_due_false_after_fresh_timestamp ... ok
test services::exercise_db::tests::search_by_category ... ok
test services::exercise_db::tests::search_by_equipment ... ok
test services::exercise_db::tests::native::is_refresh_due_true_when_no_config_entry ... ok
test services::exercise_db::tests::search_by_force ... ok
test services::exercise_db::tests::search_by_level ... ok
test services::exercise_db::tests::search_by_muscle ... ok
test services::exercise_db::tests::search_by_name ... ok
test services::exercise_db::tests::search_by_secondary_muscle ... ok
test services::exercise_db::tests::search_by_secondary_muscle_biceps ... ok
test services::exercise_db::tests::native::record_fetch_timestamp_writes_numeric_value ... ok
test services::exercise_db::tests::search_case_insensitive ... ok
test services::exercise_db::tests::search_custom_exercise_by_muscle_unified ... ok
test services::exercise_db::tests::search_custom_exercise_by_category_unified ... ok
test services::exercise_db::tests::search_custom_exercise_by_secondary_muscle_unified ... ok
test services::exercise_db::tests::search_empty_query_returns_all ... ok
test services::exercise_db::tests::search_no_match ... ok
test services::exercise_db::tests::search_with_none_equipment_does_not_match_equipment_query ... ok
test services::service_worker::tests::register_service_worker_noop_on_native ... ok
test services::wake_lock::tests::enable_wake_lock_noop_on_native ... ok
test services::exercise_db::tests::search_with_none_force_does_not_match_force_query ... ok
test utils::tests::days_since_uses_local_midnight_boundary ... ok
test utils::tests::exercise_db_url_storage_key_is_stable ... ok
test utils::tests::format_session_date_beginning_of_today ... ok
test utils::tests::format_session_date_days_ago ... ok
test utils::tests::format_session_date_end_of_yesterday ... ok
test utils::tests::format_session_date_today ... ok
test utils::tests::format_session_date_two_days_ago ... ok
test utils::tests::format_session_date_yesterday ... ok
test utils::tests::get_exercise_db_url_returns_default_on_native ... ok

test result: ok. 121 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s

Coverage Summary

Filename                                 Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover    Branches   Missed Branches     Cover
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
components/active_session.rs                 398               398     0.00%          30                30     0.00%         221               221     0.00%           0                 0         -
components/add_custom_exercise.rs             30                30     0.00%           3                 3     0.00%          24                24     0.00%           0                 0         -
components/analytics.rs                        1                 1     0.00%           1                 1     0.00%           1                 1     0.00%           0                 0         -
components/analytics_panel.rs                182               182     0.00%          32                32     0.00%         111               111     0.00%           0                 0         -
components/bottom_nav.rs                       1                 1     0.00%           1                 1     0.00%           1                 1     0.00%           0                 0         -
components/completed_exercise_log.rs          92                92     0.00%          13                13     0.00%          47                47     0.00%           0                 0         -
components/credits.rs                         18                18     0.00%           3                 3     0.00%          16                16     0.00%           0                 0         -
components/edit_custom_exercise.rs            47                47     0.00%          12                12     0.00%          32                32     0.00%           0                 0         -
components/exercise_card.rs                   44                44     0.00%           4                 4     0.00%          31                31     0.00%           0                 0         -
components/exercise_form_fields.rs           190               190     0.00%          24                24     0.00%         104               104     0.00%           0                 0         -
components/exercise_list.rs                  158               158     0.00%          13                13     0.00%          95                95     0.00%           0                 0         -
components/home.rs                            68                68     0.00%          18                18     0.00%          41                41     0.00%           0                 0         -
components/session_exercise_form.rs           28                28     0.00%          15                15     0.00%          15                15     0.00%           0                 0         -
components/session_timers.rs                  27                27     0.00%          11                11     0.00%          17                17     0.00%           0                 0         -
components/workout_log.rs                     96                96     0.00%          14                14     0.00%          60                60     0.00%           0                 0         -
main.rs                                       16                16     0.00%           7                 7     0.00%          12                12     0.00%           0                 0         -
models/mod.rs                               1506                 3    99.80%         109                 1    99.08%        1028                 2    99.81%           0                 0         -
services/exercise_db.rs                      714                 4    99.44%          66                 2    96.97%         447                 2    99.55%           0                 0         -
services/exercise_loader.rs                   56                56     0.00%           6                 6     0.00%          36                36     0.00%           0                 0         -
services/service_worker.rs                     6                 0   100.00%           2                 0   100.00%           6                 0   100.00%           0                 0         -
services/storage.rs                          365               298    18.36%          55                43    21.82%         223               176    21.08%           0                 0         -
services/wake_lock.rs                          5                 0   100.00%           2                 0   100.00%           5                 0   100.00%           0                 0         -
utils.rs                                     117                 1    99.15%          13                 0   100.00%          67                 1    98.51%           0                 0         -
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOTAL                                       4165              1758    57.79%         454               253    44.27%        2640              1045    60.42%           0                 0         -

Coverage Gate ✅ PASSED — all tested files have ≥ 90% coverage

File Lines Hit/Total Coverage Status
src/models/mod.rs 1026/1028 99%
src/services/exercise_db.rs 445/447 99%
src/services/service_worker.rs 6/6 100%
src/services/wake_lock.rs 5/5 100%
src/utils.rs 66/67 98%

@gfauredev gfauredev marked this pull request as ready for review February 22, 2026 10:22
…false + longer timeouts

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Harmonize CI/CD: CI on PRs, CD on main; move Maestro e2e to CI; fix Maestro tests Harmonize CI/CD workflows and fix Android Maestro e2e tests Feb 22, 2026
Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Harmonize CI/CD workflows and fix Android Maestro e2e tests Harmonize CI/CD: CI on PRs, CD on main; move Maestro e2e to CI; fix Maestro tests Feb 22, 2026
…e sh -c execution)

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Harmonize CI/CD: CI on PRs, CD on main; move Maestro e2e to CI; fix Maestro tests Harmonize CI/CD: CI on PRs, CD on main; fix Android Maestro e2e tests Feb 22, 2026
…ngular)

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Harmonize CI/CD: CI on PRs, CD on main; fix Android Maestro e2e tests Harmonize CI/CD and fix Android Maestro e2e tests Feb 22, 2026
…nch from CI

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Harmonize CI/CD and fix Android Maestro e2e tests Harmonize CI/CD workflows and fix Android Maestro e2e tests Feb 22, 2026
Copilot AI changed the title Fix Android Maestro e2e tests: use google_apis emulator + debug build + correct YAML Harmonize CI/CD workflows and fix Android Maestro e2e tests Feb 23, 2026
Copilot AI and others added 2 commits February 24, 2026 08:13
…t upload

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
…ibility + add CI diagnostics

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Harmonize CI/CD workflows and fix Android Maestro e2e tests Fix Android Maestro e2e tests: expose headings to Chrome WebView accessibility + harmonize CI/CD Feb 24, 2026
…oad wait

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Fix Android Maestro e2e tests: expose headings to Chrome WebView accessibility + harmonize CI/CD Fix Android Maestro e2e tests: pre-launch app with CDP socket detection + stopApp:false Feb 25, 2026
…t Activity recreation

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Fix Android Maestro e2e tests: pre-launch app with CDP socket detection + stopApp:false Fix Maestro Android e2e: correct CDP socket detection + prevent Activity recreation Feb 25, 2026
Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Fix Maestro Android e2e: correct CDP socket detection + prevent Activity recreation Fix Android Maestro e2e tests: add launchApp for CDP + dark background CSS Feb 25, 2026
…ion at 60s boundary

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Fix Android Maestro e2e tests: add launchApp for CDP + dark background CSS Fix Android Maestro e2e: resolve 60s race condition with JVM warm-up and wider timeout Feb 26, 2026
… rendering race condition

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title Fix Android Maestro e2e: resolve 60s race condition with JVM warm-up and wider timeout Fix Android Maestro e2e: eliminate UIAutomator2 rendering race condition Feb 26, 2026
@gfauredev gfauredev merged commit fcfee6b into main Feb 26, 2026
4 of 5 checks passed
@gfauredev gfauredev deleted the copilot/harmonize-ci-cd-workflow branch February 26, 2026 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants